package global

import (
	"fmt"
	"github.com/jinzhu/gorm"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"learn-gin/app/models"
	"log"
	"os"
	"time"
)

var (
	EWA_VIPER     *viper.Viper
	SUGAREDLOGGER *zap.SugaredLogger
	EWA_DB        *gorm.DB

	sections        = make(map[string]interface{})
	DatabaseSetting *DatabaseSettingS
)

// 数据库配置
type DatabaseSettingS struct {
	DBType       string
	UserName     string
	Password     string
	Host         string
	DBName       string
	Charset      string
	ParseTime    bool
	Timezone     string
	MaxIdleConns int
	MaxOpenConns int
}

func init() {
	InitLogger()
	loadConf()
	db, err := gorm.Open(DatabaseSetting.DBType,
		fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=%s",
			DatabaseSetting.UserName,
			DatabaseSetting.Password,
			DatabaseSetting.Host,
			DatabaseSetting.DBName,
			DatabaseSetting.Charset,
			DatabaseSetting.ParseTime,
			DatabaseSetting.Timezone,
		))
	if err != nil {
		panic("连接数据库失败")
	}

	db.LogMode(true)
	db.SingularTable(true)
	db.DB().SetMaxIdleConns(DatabaseSetting.MaxIdleConns)
	db.DB().SetMaxOpenConns(DatabaseSetting.MaxOpenConns)
	db.AutoMigrate(&models.User{})
	EWA_DB = db
}

// 读取配置到全局变量
func loadConf() {
	EWA_VIPER = viper.New()
	EWA_VIPER.SetConfigName("config")
	EWA_VIPER.AddConfigPath("config")
	EWA_VIPER.SetConfigType("yaml")
	err := EWA_VIPER.ReadInConfig()
	if err != nil {
		panic("读取配置到全局变量err:" + err.Error())
	}

	err = ReadSection("Database", &DatabaseSetting)
	if err != nil {

	}

	fmt.Println("setting:")
	fmt.Println(DatabaseSetting)
}

// 读取指定的一段
func ReadSection(k string, v interface{}) error {
	err := EWA_VIPER.UnmarshalKey(k, v)
	if err != nil {
		return err
	}

	if _, ok := sections[k]; !ok {
		sections[k] = v
	}
	return nil
}

func InitLogger() {
	core := zapcore.NewCore(enc(), wsV2(), enab())
	logger := zap.New(core)
	SUGAREDLOGGER = logger.Sugar()
	defer SUGAREDLOGGER.Sync()
}

func enc() zapcore.Encoder {
	cfg := zap.NewProductionEncoderConfig()
	cfg.TimeKey = "time"
	cfg.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
	return zapcore.NewJSONEncoder(cfg)
}

func ws() zapcore.WriteSyncer {

	logFileName := fmt.Sprintf("logs/%v.log", time.Now().Format("2006-01-02"))
	if _, err := os.Stat(logFileName); err == nil {
		if logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_APPEND, 0666); err == nil {
			return zapcore.AddSync(logFile)
		}
	}
	logFile, err := os.Create(logFileName)
	if err != nil {
		log.Fatal(err)
	}
	return zapcore.AddSync(logFile)
}

func wsV2() zapcore.WriteSyncer {
	return zapcore.NewMultiWriteSyncer(ws(), zapcore.AddSync(os.Stdout))
}

func enab() zapcore.LevelEnabler {
	return zapcore.DebugLevel
}
